package top.xia17.plugins.fast.auth.captcha;

import cn.hutool.core.util.StrUtil;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.awt.*;

/**
 * 图形验证码工具
 *
 * @author xia17
 * @date 2022/2/21
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class CaptchaUtil {

    private final CaptchaProperties captchaProperties;

    public CaptchaProperties getCaptchaProperties() {
        return captchaProperties;
    }

    /**
     * 创建验证码实例
     *
     * @return /
     */
    public Captcha createCaptcha() {
        return createCaptcha(captchaProperties);
    }

    /**
     * 获取验证码的值
     *
     * @return /
     */
    public static String getText(Captcha captcha) {
        //当验证码类型为 arithmetic时且长度 >= 2 时，captcha.text()的结果有几率为浮点型
        String captchaValue = captcha.text();
        if (captcha.getCharType() - 1 == CaptchaType.ARITHMETIC.ordinal() && captchaValue.contains(".")) {
            captchaValue = captchaValue.split("\\.")[0];
        }
        return captchaValue;
    }

    /**
     * 创建验证码实例
     *
     * @param captchaProperties 配置信息
     * @return /
     */
    public static Captcha createCaptcha(CaptchaProperties captchaProperties) {
        // 类型
        CaptchaType type = captchaProperties.getType();
        Captcha captcha;
        switch (type) {
            case ARITHMETIC -> {
                // 算术类型 https://gitee.com/whvse/EasyCaptcha
                captcha = new FixedArithmeticCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
                // 几位数运算，默认是两位
                captcha.setLen(captchaProperties.getLength());
            }
            case CHINESE -> {
                captcha = new ChineseCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
                captcha.setLen(captchaProperties.getLength());
            }
            case CHINESE_GIF -> {
                captcha = new ChineseGifCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
                captcha.setLen(captchaProperties.getLength());
            }
            case GIF -> {
                captcha = new GifCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
                captcha.setLen(captchaProperties.getLength());
            }
            case SPEC -> {
                captcha = new SpecCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
                captcha.setLen(captchaProperties.getLength());
            }
            default -> throw new RuntimeException("验证码配置信息错误！正确配置查看 CaptchaType ");
        }
        if (StrUtil.isNotBlank(captchaProperties.getFontName())) {
            captcha.setFont(new Font(captchaProperties.getFontName(), Font.PLAIN, captchaProperties.getFontSize()));
        }
        return captcha;
    }

    /**
     * 浮点型计算类型
     */
    static class FixedArithmeticCaptcha extends ArithmeticCaptcha {
        public FixedArithmeticCaptcha(int width, int height) {
            super(width, height);
        }

        @Override
        protected char[] alphas() {
            // 生成随机数字和运算符
            int n1 = num(1, 10), n2 = num(1, 10);
            int opt = num(3);

            // 计算结果
            int res = new int[]{n1 + n2, n1 - n2, n1 * n2}[opt];
            // 转换为字符运算符
            char optChar = "+-x".charAt(opt);

            this.setArithmeticString(String.format("%s%c%s=?", n1, optChar, n2));
            this.chars = String.valueOf(res);

            return chars.toCharArray();
        }
    }


}
